<template>
  <view
    class="container"
    :style="{ backgroundColor: config.isNight ? '#0D0D0D' : config.bgColor }"
    @tap="startSleep"
  >
    <uni-nav-bar
      left-icon="arrowleft"
      background-color="transparent"
      :color="config.isNight ? '#474747' : config.color"
      :status-bar="true"
      :title="name"
      @click-left="back"
    />
    <view class="story-content tui-flex-1">
      <view
        class="story-status tui-flex"
        :style="{ color: config.isNight ? '#474747' : config.color }"
      >
        <text class="tui-flex-1">{{ chapterTitle }}</text>
        <view>
          {{ currentIndex + 1 }}/
          {{ config.animate == "上下" ? allPage - 1 : allPage }}
        </view>
      </view>
      <!-- 阅读内容 Start -->
      <block v-if="config.animate == 'none'">
        <scroll-view
          scroll-y
          class="story-page"
          :style="{
            height: pageHeight + 'px',
            color: config.isNight ? '#474747' : config.color,
            fontSize: config.fontSize + 'rpx',
            lineHeight: config.lineHeight + 'rpx'
          }"
          :scroll-top="scrollTop"
        >
          <view :style="{ height: contentHeight }">
            <text class="story-page-text" space="nbsp">{{ content }}</text>
          </view>
        </scroll-view>
        <view class="tap-container" @touchstart="touchstart" @touchend="touchend">
          <view class="tui-col-5 tap-zone" @tap="prevPage"></view>
          <view class="tui-col-2 tap-zone" @tap="showSetting"></view>
          <view class="tui-col-5 tap-zone" @tap="nextPage"></view>
        </view>
      </block>

      <block v-else-if="config.animate == '平移'">
        <view
          class="story-page"
          :style="{
            height: pageHeight + 'px',
            color: 'transparent',
            fontSize: config.fontSize + 'rpx',
            lineHeight: config.lineHeight + 'rpx'
          }"
          @tap="handleTouch"
        >
          <view :style="{ height: contentHeight }">
            <text class="story-page-text" space="nbsp">{{ content }}</text>
          </view>
          <swiper circular class="story-swiper" :current="currentIndex" @change="swiperPage">
            <swiper-item v-for="n in allPage" :key="n">
              <scroll-view
                scroll-y
                class="story-page"
                :style="{
                  height: pageHeight + 'px',
                  color: config.isNight ? '#474747' : config.color,
                  fontSize: config.fontSize + 'rpx',
                  lineHeight: config.lineHeight + 'rpx',
                  padding: 0
                }"
                :scroll-top="n * pageHeight"
              >
                <view :style="{ height: contentHeight }">
                  <text class="story-page-text" space="nbsp">{{ content }}</text>
                  <!-- 下边一行为了撑起最后一页不满的情况下 -->
                  <view v-if="n == allPage - 1" :style="{ height: pageHeight + 'px' }"></view>
                </view>
              </scroll-view>
              <!-- 下边一行时遮罩，防止点击滑动等操作影响阅读 -->
              <view class="tap-container"></view>
            </swiper-item>
          </swiper>
        </view>
      </block>

      <block v-else-if="config.animate == '上下'">
        <scroll-view
          scroll-y
          class="story-page"
          :style="{
            height: pageHeight + 'px',
            color: config.isNight ? '#474747' : config.color,
            fontSize: config.fontSize + 'rpx',
            lineHeight: config.lineHeight + 'rpx',
            overflowY: 'auto'
          }"
          :scroll-top="scrollTop"
          @scroll="handleScroll"
          @tap="showSetting"
        >
          <view class="story-page-text">
            <text space="nbsp">{{ content }}</text>
            <view class="tui-flex" style="margin-top:10rpx;">
              <tui-button
                type="primary"
                size="mini"
                class="tui-flex-1"
                shape="circle"
                class-name="w-100"
                :plain="true"
                :disabled="!prev"
                @click="prevChapter(true)"
              >上一章</tui-button>
              <tui-button
                type="primary"
                size="mini"
                class="tui-flex-1"
                shape="circle"
                class-name="w-100"
                :plain="true"
                :disabled="!next"
                @click="nextChapter()"
              >下一章</tui-button>
            </view>
          </view>
        </scroll-view>
      </block>
      <!-- 阅读内容 End -->
    </view>
    <view class="mask-screen" @tap="hideModal" v-show="showModalStatus"></view>
    <view
      :animation="animationData"
      class="story-setting"
      v-show="showModalStatus && !settingOpened && !showOtherSources"
      :style="{
        backgroundColor: config.isNight ? '#1E1E1E' : '#2B2B2B',
        color: config.isNight ? '#979797' : '#fff'
      }"
    >
      <view
        class="story-setting-mode"
        :style="{ borderColor: config.isNight ? '#979797' : '#1E1E1E' }"
        hover-class="tui-opcity"
        @tap="switchNight"
      >
        <image
          mode="widthFix"
          style="width:100%;"
          :src="
            config.isNight
              ? '/static/images/stories/Sun.png'
              : '/static/images/stories/Moon.png'
          "
        />
      </view>
      <view class="story-setting-status">
        <view class="story-setting-status-text" hover-class="tui-opcity" @tap="prevChapter">上一章</view>
        <view class="tui-flex-1">
          <slider
            min="1"
            block-size="12"
            :activeColor="config.isNight ? '#488' : '#6cc'"
            :max="allPage"
            :value="currentIndex + 1"
            @change="goPage"
          />
        </view>
        <view class="story-setting-status-text" hover-class="tui-opcity" @tap="nextChapter">下一章</view>
      </view>
      <view class="story-setting-btn">
        <view class="story-setting-btn-item" hover-class="tui-gray" @tap="goCatalogs">
          <tui-icon name="listview" :size="22" :color="config.isNight ? '#979797' : '#fff'" />
          <view class="story-setting-btn-text">目录</view>
        </view>
        <view class="story-setting-btn-item" hover-class="tui-gray" @tap="switchSource">
          <tui-icon name="refresh" :size="22" :color="config.isNight ? '#979797' : '#fff'" />
          <view class="story-setting-btn-text">换源</view>
        </view>
        <view class="story-setting-btn-item" hover-class="tui-gray" @tap="goDetail">
          <tui-icon name="strategy" :size="22" :color="config.isNight ? '#979797' : '#fff'" />
          <view class="story-setting-btn-text">书籍详情</view>
        </view>
        <view class="story-setting-btn-item" hover-class="tui-gray" @tap="openSetting">
          <tui-icon name="setup" :size="22" :color="config.isNight ? '#979797' : '#fff'" />
          <view class="story-setting-btn-text">设置</view>
        </view>
      </view>
    </view>
    <view
      :animation="animationData"
      class="story-setting"
      v-show="showModalStatus && settingOpened"
      :style="{
        backgroundColor: config.isNight ? '#1E1E1E' : '#2B2B2B',
        color: config.isNight ? '#979797' : '#fff'
      }"
    >
      <view class="story-setting-status">
        <view class="tui-flex-1 story-setting-status">
          <image
            mode="widthFix"
            src="/static/images/stories/Sun.png"
            style="width:20rpx;height:20rpx;"
          />
          <slider
            max="1"
            block-size="12"
            step="0.1"
            class="brightness"
            :activeColor="config.isNight ? '#488' : '#6cc'"
            :value="config.brightness"
            @change="adjustBright"
          />
          <image
            mode="widthFix"
            src="/static/images/stories/Sun.png"
            style="width:40rpx;height:40rpx;"
          />
        </view>
        <tui-tag
          size="small"
          style="margin-left:20rpx;"
          :plain="true"
          :type="config.followSysBright ? 'high-green' : 'gray'"
          @click="followSysBright"
        >跟随系统</tui-tag>
      </view>
      <scroll-view scroll-x class="story-setting-theme">
        <view
          class="theme-item"
          style="background-color:#D5EED1;color:#282D29;"
          :class="{ active: config.bgColor == '#D5EED1' }"
          @tap="switchTheme('#D5EED1', '#282D29')"
        >护眼</view>
        <view
          class="theme-item"
          style="background-color:#F9F3DD;color:#3F3B30;"
          :class="{ active: config.bgColor == '#F9F3DD' }"
          @tap="switchTheme('#F9F3DD', '#3F3B30')"
        >复古</view>
        <view
          class="theme-item"
          style="background-color:#F0EBE5;color:#756148;"
          :class="{ active: config.bgColor == '#F0EBE5' }"
          @tap="switchTheme('#F0EBE5', '#756148')"
        >温馨</view>
        <view
          class="theme-item"
          style="background-color:#FEE2F0;color:#444243;"
          :class="{ active: config.bgColor == '#FEE2F0' }"
          @tap="switchTheme('#FEE2F0', '#444243')"
        >粉嫩</view>
        <view
          class="theme-item"
          style="background-color:#3A4149;color:#90979F;"
          :class="{ active: config.bgColor == '#3A4149' }"
          @tap="switchTheme('#3A4149', '#90979F')"
        >黯黑</view>
      </scroll-view>
      <view class="story-setting-row tui-flex">
        <view class="tui-flex tui-flex-1 tui-align-center">
          <tui-tag :plain="true" size="small" type="gray" @click="reduceFontSize">Aa-</tui-tag>
          <tui-tag size="small" type="gray">{{ config.fontSize }}</tui-tag>
          <!-- <view class="setting-font-size">{{ config.fontSize }}</view> -->
          <tui-tag :plain="true" size="small" type="gray" @click="plusFonotSize">Aa+</tui-tag>
        </view>
        <view class="tui-flex tui-flex-1 tui-align-center">
          <tui-tag :plain="true" size="small" type="gray" @click="reduceLineHeight">三-</tui-tag>
          <view style="width:20rpx"></view>
          <tui-tag :plain="true" size="small" type="gray" @click="plusLineHeight">三+</tui-tag>
        </view>
      </view>
    </view>

    <view
      :animation="animationData"
      class="story-setting"
      v-show="showModalStatus && showOtherSources"
      :style="{
        backgroundColor: config.isNight ? '#1E1E1E' : '#2B2B2B',
        color: config.isNight ? '#979797' : '#fff'
      }"
    >
      <view class="tui-flex">
        <tui-button
          type="danger"
          size="small"
          class="tui-flex tui-flex-1"
          class-name="tui-flex-1"
          :disabled="sourceLoading"
          :stop="true"
          @click="addOtherSources"
        >
          <tui-icon name="plus" :rpx="true" color="#fff" />添加源
        </tui-button>
        <view style="width:20rpx;"></view>
        <tui-button
          type="primary"
          size="small"
          class="tui-flex tui-flex-1"
          class-name="tui-flex-1"
          :disabled="sourceLoading || sourceData.length == 0"
          :stop="true"
          @click="loadOtherSources(true)"
        >
          <tui-icon name="refresh" :rpx="true" color="#fff" />刷新源
        </tui-button>
      </view>
      <view style="max-height:420rpx;overflow-y:auto;">
        <tui-swipe-action
          v-for="(item, index) in sourceData"
          :key="index"
          :actions="actions"
          @click="deleteOtherSource"
          :params="item"
        >
          <template v-slot:content>
            <view
              class="tui-flex tui-flex-1 tui-flex-column"
              hover-class="tui-gray"
              style="padding:20rpx 0;line-height:50rpx;"
              :style="{
                borderColor: config.isNight ? '#7F7F7F' : '#fff',
                borderTop: index ? '1rpx solid' : 'none'
              }"
              @click="changeSource(index)"
            >
              <view
                style="font-size:30rpx;"
                :style="{ color: !config.isNight ? '#fff' : '#7F7F7F' }"
              >{{ item.latest_chapter_name }}</view>
              <view
                style="font-size:28rpx;"
                :style="{ color: !config.isNight ? '#BABABA' : '#999' }"
              >更新于：{{ item.update_time_cover }}</view>
              <view
                style="font-size:26rpx;"
                :style="{ color: !config.isNight ? '#9D9D9D' : '#636363' }"
              >来源：{{ item.source_name }}</view>
            </view>
          </template>
        </tui-swipe-action>
        <tui-loadmore :visible="sourceLoading" :index="3" type="primary"></tui-loadmore>
        <tui-nomore
          :visible="!sourceLoading && !sourceData.length"
          :text="other_sources.length ? '没有搜索到数据' : '没有备用源，请添加'"
          :bgcolor="config.isNight ? '#1E1E1E' : '#2B2B2B'"
        ></tui-nomore>
      </view>
    </view>

    <tui-page-loading type="spin" :show="loading" />
  </view>
</template>

<script>
import tuiIcon from "@/components/icon/icon.vue";
import tuiTag from "@/components/tag/tag.vue";
import tuiPageLoading from "@/components/page-loading/page-loading.vue";
import uniNavBar from "@/components/uni-nav-bar/uni-nav-bar.vue";
import tuiButton from "@/components/button/button";
import tuiLoadmore from "@/components/loadmore/loadmore";
import tuiNomore from "@/components/nomore/nomore";
import tuiSwipeAction from "@/components/swipe-action/swipe-action";
import { mapMutations, mapState, mapActions } from "vuex";
import { stringify } from "qs";
import { format } from "timeago.js";
import { equalObj } from "@/utils/util";
let t;

export default {
  components: {
    tuiIcon,
    tuiTag,
    tuiPageLoading,
    uniNavBar,
    tuiButton,
    tuiLoadmore,
    tuiNomore,
    tuiSwipeAction
  },
  data() {
    return {
      _id: 0,
      name: "阅读",
      chapterTitle: "",
      content: "",
      source_id: "",
      read_url: "",
      url: "",
      currentIndex: 0,
      next: "",
      prev: "",
      scrollTop: 0,
      allHeight: 0,
      contentHeight: "auto",
      showModalStatus: false,
      animationData: "",
      settingOpened: false,
      loadData: {},
      oldData: {},
      preLoading: false,
      // 点击了上一章 赋值loadData,阻止preLoad再次赋值loadData覆盖
      preving: false,
      loading: false,
      touch: { x: 0, y: 0 },
      windowHeight: uni.getSystemInfoSync().windowHeight - 64 - uni.upx2px(46),
      windowWidth: uni.getSystemInfoSync().windowWidth,
      oldConfig: {},
      other_sources: [],
      showOtherSources: false,
      sourceLoading: false,
      sourceData: [],
      // 备用源滑动操作
      actions: [
        {
          name: "删除",
          color: "#fff",
          fontsize: 30, //单位upx
          width: 80, //单位px
          background: "#ed3f14"
        }
      ]
    };
  },
  computed: {
    ...mapState(["config", "bookshelfs"]),
    pageHeight() {
      return parseInt(this.windowHeight / this.fontHeight) * this.fontHeight;
    },
    allPage() {
      const allPage = Math.ceil(this.allHeight / this.pageHeight);
      // 解决最后一页内容不足一页时，也要撑起一页
      this.contentHeight = allPage * this.pageHeight + "px";
      return allPage;
    },
    fontHeight() {
      return uni.upx2px(this.config.lineHeight);
    }
  },
  watch: {
    currentIndex() {
      if (this.config.animate == "none") {
        // console.log("currentIndex");
        this.scrollTop = this.currentIndex * this.pageHeight;
      }
    },
    fontHeight() {
      this.calcHeight(this.currentIndex);
    },
    preLoading() {
      if (
        this.loading &&
        !this.preLoading &&
        Object.keys(this.loadData).length > 0
      ) {
        console.log("preLoading");
        this.loading = false;
        this.nextChapter();
      }
    },
    bookshelfs() {
      if (this._id) {
        const book = this.bookshelfs.find(bs => bs._id == this._id);
        if (!book) {
          this.other_sources = [];
        }
        this.other_sources = book.other_sources || [];
      }
    }
  },
  onLoad(options) {
    // console.log(options);
    const { source_id, read_url, url, page, _id, name } = options;
    if (!_id && (!source_id || !read_url || !url)) {
      this.tui.toast("参数缺失");
      setTimeout(() => {
        uni.navigateBack({
          delta: 1
        });
      }, 1000);
    } else if (_id && !url) {
      const book = this.bookshelfs.find(bs => bs._id == options._id);
      if (!book) {
        this.tui.toast("参数缺失");
        setTimeout(() => {
          uni.navigateBack({
            delta: 1
          });
        }, 1000);
      } else {
        this._id = book._id;
        this.name = book.name;
        this.source_id = book.source_id;
        this.read_url = book.read_url;
        this.url = book.url;
        this.currentIndex = parseInt(book.page || 0);
        this.other_sources = book.other_sources || [];
        this.sourceData = [];
        this.readContent();
      }
    } else {
      this._id = _id;
      this.name = name;
      this.source_id = source_id;
      this.read_url = read_url;
      this.url = url;
      this.currentIndex = parseInt(page || 0);
      this.readContent();
    }
    // 设置阅读亮度
    uni.getScreenBrightness({
      success: res => {
        const config = { sysBright: res.value };
        if (this.config.followSysBright) {
          config.brightness = res.value;
        } else {
          uni.setScreenBrightness({
            value: this.config.brightness
          });
        }
        this.setConfig(config);
      }
    });
    // 设置休眠
    this.startSleep();
  },
  // 上传阅读进度以及配置信息到服务器保存
  onUnload() {
    this.saveRead();
  },
  onHide() {
    this.saveRead();
  },
  onShow() {
    this.hideModal();
    this.oldConfig = this.config;
    this.startSleep();
  },
  methods: {
    ...mapMutations(["setConfig", "setBookshelfs"]),
    saveRead() {
      // 保存配置信息
      if (this.config._id && !equalObj(this.oldConfig, this.config)) {
        const config = { ...this.config };
        delete config._id;
        delete config._openid;
        this.db
          .collection("config")
          .doc(this.config._id)
          .update({
            data: config
          })
          .then(res => {
            console.log("saveConfig", res);
          });
      }
      // 保存阅读进度
      if (this._id) {
        this.db
          .collection("bookshelfs")
          .doc(this._id)
          .update({
            data: {
              url: this.url,
              page: this.currentIndex,
              hasNew: false,
              read_time: new Date().getTime()
            }
          })
          .then(res => {
            console.log("saveReadProgress", res);
            if (res.stats && res.stats.updated) {
              const book = [],
                others = [];
              // 设置进度 以及 取消更新显示
              this.bookshelfs.forEach(bs => {
                if (bs._id == this._id) {
                  bs.url = this.url;
                  bs.page = this.currentIndex;
                  bs.hasNew = false;
                  book.push(bs);
                } else {
                  others.push(bs);
                }
              });
              this.setBookshelfs([...book, ...others]);
            }
          });
      }
      t && clearTimeout(t);
      uni.setKeepScreenOn({
        keepScreenOn: false
      });
    },
    readContent() {
      this.loading = true;
      this.callFunc({
        name: "startRead",
        data: {
          source_id: this.source_id,
          url: this.url
        }
      })
        .then(res => {
          if (res.result.errMsg == "ok") {
            const { name, content, next, prev } = res.result.data;
            this.chapterTitle = name;
            this.content = content;
            if (prev.length < next.length) {
              // 没有上一章
              this.prev = "";
              this.next = next;
              this.oldData = {};
            } else if (prev.length > next.length) {
              // 没有下一章
              this.next = "";
              this.prev = prev;
              this.loadData = {};
            } else {
              this.next = next;
              this.prev = prev;
            }
            this.preLoad();
            const currentIndex = this.currentIndex;
            this.currentIndex = 0;
            this.$nextTick(() => this.calcHeight(currentIndex));
          } else {
            this.tui.toast(res.result.errMsg);
          }
          this.loading = false;
        })
        .catch(err => {
          this.tui.toast("请求失败，请重试或者换源阅读");
          this.loading = false;
        });
    },
    // 后台预加载下一章
    preLoad() {
      this.loadData = {};
      if (!this.next) {
        return;
      }
      this.preLoading = true;
      this.callFunc({
        name: "startRead",
        data: {
          source_id: this.source_id,
          url: this.next
        }
      })
        .then(res => {
          if (
            res.result.errMsg == "ok" &&
            !this.preving &&
            Object.keys(this.loadData).length == 0
          ) {
            const { name, content, next, prev } = res.result.data;
            this.loadData.chapterTitle = name;
            this.loadData.content = content;
            if (prev.length < next.length) {
              this.loadData.prev = "";
              this.loadData.next = next;
            } else if (prev.length > next.length) {
              this.loadData.prev = prev;
              this.loadData.next = "";
            } else {
              this.loadData.next = next;
              this.loadData.prev = prev;
            }
          } else if (res.result.errMsg != "ok") {
            this.tui.toast(res.result.errMsg);
          }
          this.preLoading = false;
        })
        .catch(err => {
          console.log(err);
          this.preLoading = false;
          if (this.loading) {
            this.tui.toast("请求失败，请重试");
            this.loading = false;
          }
        });
    },
    calcHeight(currentIndex) {
      this.contentHeight = "auto";
      const query = uni.createSelectorQuery().in(this);
      query
        .select(".story-page .story-page-text")
        .boundingClientRect(data => {
          this.allHeight = data.height;
          // 初始页码
          if (typeof currentIndex == "number") {
            this.currentIndex = currentIndex;
          } else if (currentIndex === true) {
            this.$nextTick(() => (this.currentIndex = this.allPage - 1));
          } else {
            this.currentIndex = 0;
          }
          if (this.config.animate == "上下") {
            this.$nextTick(() => {
              this.scrollTop = this.currentIndex * this.pageHeight;
            });
          }
        })
        .exec();
    },
    handleTouch(e) {
      if (e.detail.x > (this.windowWidth / 12) * 7) {
        this.nextPage();
      } else if (e.detail.x < (this.windowWidth / 12) * 5) {
        this.prevPage();
      } else {
        this.showSetting();
      }
    },
    // 上下滚动时
    handleScroll(e) {
      this.scrollTop = e.detail.scrollTop;
      // console.log(this.scrollTop, this.pageHeight, this.allHeight);
      this.currentIndex = Math.floor(this.scrollTop / this.pageHeight);
    },
    nextPage() {
      // console.log(this.currentIndex, this.allPage);
      if (this.currentIndex + 1 >= this.allPage) {
        // 下一章
        this.nextChapter();
      } else {
        this.currentIndex++;
      }
    },
    prevPage() {
      if (this.currentIndex > 0) {
        this.currentIndex--;
      } else {
        // 上一章
        this.prevChapter(true);
      }
    },
    // 显示阅读设置
    showSetting() {
      let animation = uni.createAnimation({
        duration: 200,
        timingFunction: "linear",
        delay: 0
      });
      animation.translateY(uni.upx2px(712)).step();
      this.animationData = animation.export();
      this.showModalStatus = true;
      this.$nextTick(() => {
        animation.translateY(0).step();
        this.animationData = animation.export();
      });
    },
    hideModal() {
      this.showModalStatus = false;
      this.settingOpened = false;
      this.showOtherSources = false;
    },
    // 设置窗口的滑动跳页
    goPage(e) {
      this.currentIndex = e.detail.value - 1;
    },
    // 滑动翻页
    swiperPage(e) {
      if (this.currentIndex + 1 == this.allPage && e.detail.current == 0) {
        // 下一章
        this.nextChapter();
      } else if (
        this.currentIndex == 0 &&
        e.detail.current + 1 == this.allPage
      ) {
        this.prevChapter(true);
      } else {
        this.currentIndex = e.detail.current;
      }
    },
    // 上一章
    prevChapter(last) {
      if (!this.prev) {
        return;
      }
      this.preving = true;
      if (Object.keys(this.oldData).length > 0) {
        this.loadData = {
          chapterTitle: this.chapterTitle,
          content: this.content,
          next: this.next,
          prev: this.prev
        };
        this.chapterTitle = this.oldData.chapterTitle;
        this.content = this.oldData.content;
        this.url = this.oldData.url;
        this.next = this.oldData.next;
        this.prev = this.oldData.prev;
        this.oldData = {};
        this.$nextTick(() => this.calcHeight(last));
        return;
      }

      this.loading = true;
      this.callFunc({
        name: "startRead",
        data: {
          source_id: this.source_id,
          url: this.prev
        }
      }).then(res => {
        if (res.result.errMsg == "ok") {
          const { name, content, next, prev } = res.result.data;
          this.loadData = {
            chapterTitle: this.chapterTitle,
            content: this.content,
            next: this.next,
            prev: this.prev
          };
          this.chapterTitle = name;
          this.content = content;
          this.url = this.prev;
          this.next = next;
          this.prev = prev;
          this.oldData = {};
          this.$nextTick(() => this.calcHeight(last));
        } else {
          this.tui.toast(res.result.errMsg);
        }
        this.loading = false;
      });
    },
    // 下一章
    nextChapter() {
      if (!this.next) {
        this.showModalStatus = true;
        this.switchSource();
        return;
      }
      this.preving = false;
      if (this.preLoading) {
        this.loading = true;
        return;
      }
      if (Object.keys(this.loadData).length > 0) {
        this.oldData = {
          chapterTitle: this.chapterTitle,
          content: this.content,
          url: this.url,
          next: this.next,
          prev: this.prev
        };
        this.chapterTitle = this.loadData.chapterTitle;
        this.content = this.loadData.content;
        this.url = this.next;
        this.next = this.loadData.next;
        this.prev = this.loadData.prev;
        if (this.config.animate == "上下") {
          this.scrollTop = -1;
        }
        this.$nextTick(() => this.calcHeight(0));
        this.preLoad();
      }
    },
    // 切换夜间模式
    switchNight() {
      this.setConfig({ isNight: !this.config.isNight });
    },
    // 目录
    goCatalogs() {
      const { source_id, read_url, url, _id } = this;
      uni.navigateTo({
        url:
          "/pages/catalog/catalog?" +
          stringify({ source_id, read_url, url, _id })
      });
    },
    // 换源
    switchSource() {
      if (!this._id) {
        this.tui.toast("请先将书籍加入书架");
        return;
      }
      this.showOtherSources = true;
      if (
        this.sourceData.length == 0 &&
        this.other_sources.length > 0 &&
        !this.sourceLoading
      ) {
        this.loadOtherSources();
      }
    },
    // 请求其他源
    loadOtherSources(init) {
      if (init) {
        // 刷新源
        this.sourceData = [];
      }
      this.sourceLoading = true;
      // console.log(this.other_sources);
      if (this.other_sources.length == 0) {
        this.sourceLoading = false;
      }
      this.other_sources.forEach(source => {
        this.callFunc({
          name: "bookDetail",
          data: {
            source_id: source.source_id,
            read_url: source.read_url
          }
        })
          .then(res => {
            // console.log(res);
            if (res.result && res.result.errMsg == "ok") {
              this.sourceData.push({
                ...res.result.data,
                update_time_cover: format(res.result.data.update_time, "zh_CN")
              });
            }
            if (this.sourceData.length == this.other_sources.length) {
              this.sourceLoading = false;
            }
          })
          .catch(err => {
            console.log(err);
            this.tui.toast("请求失败，请重试");
            this.sourceLoading = false;
          });
      });
    },
    // 添加备用源
    addOtherSources() {
      uni.navigateTo({
        url: "/pages/add-source/add-source?_id=" + this._id
      });
    },
    // 切换至源
    changeSource(index) {
      const { _id, chapterTitle } = this;
      const {
        source_id,
        read_url,
        author,
        cover,
        latest_chapter_url,
        source_name
      } = this.sourceData[index];
      uni.navigateTo({
        url:
          "/pages/catalog/catalog?" +
          stringify({
            source_id,
            read_url,
            chapterTitle,
            _id,
            author,
            cover,
            latest_chapter_url,
            source_name
          })
      });
    },
    // 删除其他源
    deleteOtherSource({ index, item }) {
      const { _id, other_sources } = this;
      const { source_id } = item;
      const otherSources = [];
      other_sources.forEach(v => {
        if (v.source_id != source_id) {
          otherSources.push(v);
        }
      });
      this.db
        .collection("bookshelfs")
        .doc(_id)
        .update({
          data: {
            other_sources: otherSources
          }
        })
        .then(res => {
          if (res.stats && res.stats.updated == 1) {
            const bookshelfs = [];
            this.bookshelfs.forEach(bs => {
              if (bs._id == _id) {
                bs.other_sources = otherSources;
              }
              bookshelfs.push(bs);
            });
            this.setBookshelfs(bookshelfs);
            this.sourceData.splice(index, 1);
          } else {
            this.tui.toast(res.errMsg);
          }
        })
        .catch(err => {
          this.tui.toast("删除失败");
        });
    },
    // 书籍详情
    goDetail() {
      const { source_id, read_url } = this;
      uni.navigateTo({
        url:
          "/pages/detail/detail?" +
          stringify({ source_id, read_url }, { encode: false })
      });
    },
    // 设置
    openSetting() {
      let animation = uni.createAnimation({
        duration: 200,
        timingFunction: "linear",
        delay: 0
      });
      animation.translateY(uni.upx2px(712)).step();
      this.animationData = animation.export();
      this.settingOpened = true;
      this.$nextTick(() => {
        animation.translateY(0).step();
        this.animationData = animation.export();
      });
    },
    // 调节亮度
    adjustBright(e) {
      uni.setScreenBrightness({
        value: e.detail.value,
        success: () => {
          this.setConfig({
            followSysBright: false,
            brightness: e.detail.value
          });
        }
      });
    },
    // 切换跟随系统亮度
    followSysBright() {
      if (this.config.followSysBright) {
        this.setConfig({ followSysBright: false });
      } else {
        uni.setScreenBrightness({
          value: this.config.sysBright,
          success: () => {
            this.setConfig({
              followSysBright: true,
              brightness: this.config.sysBright
            });
          }
        });
      }
    },
    // 切换背景色 主题
    switchTheme(bgColor, color) {
      this.setConfig({
        bgColor,
        color,
        isNight: false
      });
    },
    // 字体设置
    reduceFontSize() {
      const { fontSize, lineHeight } = this.config;
      if (fontSize > 30) {
        this.setConfig({ fontSize: fontSize - 2, lineHeight: lineHeight - 2 });
      }
    },
    plusFonotSize() {
      const { fontSize, lineHeight } = this.config;
      if (fontSize < 50) {
        this.setConfig({ fontSize: fontSize + 2, lineHeight: lineHeight + 2 });
      }
    },
    // 行高设置
    reduceLineHeight() {
      const { fontSize, lineHeight } = this.config;
      if (lineHeight > fontSize) {
        this.setConfig({ lineHeight: lineHeight - 2 });
      }
    },
    plusLineHeight() {
      const { fontSize, lineHeight } = this.config;
      if (lineHeight < fontSize * 2.5) {
        this.setConfig({ lineHeight: lineHeight + 2 });
      }
    },
    // 滑动翻页
    touchstart(e) {
      const touch = e.touches[0] || e.changedTouches[0];
      this.touch.x = touch.pageX;
      this.touch.y = touch.pageY;
    },
    touchend(e) {
      const touch = e.touches[0] || e.changedTouches[0];
      if (this.touch.x - touch.pageX > 50) {
        this.nextPage();
      } else if (touch.pageX - this.touch.x > 50) {
        this.prevPage();
      }
      this.startSleep();
    },
    // 顶部导航栏按钮返回事件
    back() {
      uni.navigateBack({
        delta: 1
      });
    },
    startSleep() {
      // console.log('startSleep')
      // 休眠重新开机计时
      uni.setKeepScreenOn({
        keepScreenOn: true
      });
      if (!this.config.sleep) {
        return;
      }
      t && clearTimeout(t);
      t = setTimeout(() => {
        uni.setKeepScreenOn({
          keepScreenOn: false
        });
      }, this.config.sleep * 60 * 1000);
    }
  }
};
</script>

<style>
page,
.container {
  height: 100%;
  /* overflow-y: hidden */
}
.story-content {
  position: relative;
}
.story-status {
  font-size: 20rpx;
  padding: 10rpx 20rpx;
  line-height: 26rpx;
}
.story-page {
  padding: 0 20rpx;
  line-height: 1;
  overflow-y: hidden;
  width: auto;
  position: relative;
}
.story-page::-webkit-scrollbar {
  display: none;
  /* width: 0;
  height: 0;
  color: transparent; */
}
.tap-container {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
.tap-zone {
  height: 100%;
  float: left;
}
.mask-screen {
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  opacity: 0.5;
  overflow: hidden;
  z-index: 9;
}
.story-setting {
  width: 100%;
  position: fixed;
  bottom: 0;
  left: 0;
  z-index: 10;
  padding: 20rpx 50rpx;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
}
.story-setting-mode {
  position: absolute;
  right: 40rpx;
  top: -80rpx;
  width: 50rpx;
  height: 50rpx;
  border-radius: 50%;
  border-width: 1rpx;
  border-style: solid;
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center;
}
.story-setting-status {
  display: flex;
  align-items: center;
  padding-top: 10rpx;
}
.story-setting-status-text {
  font-size: 26rpx;
  border-radius: 10rpx;
}
.story-setting-btn {
  display: flex;
  padding: 20rpx 0;
}
.story-setting-btn-item {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  border-radius: 10rpx;
}
.story-setting-btn-text {
  font-size: 26rpx;
}
.brightness {
  flex: 1;
  margin: 10rpx;
}
.story-setting-theme {
  white-space: nowrap;
  padding: 20rpx 0;
  height: 80rpx;
}
.theme-item {
  display: inline-block;
  width: 130rpx;
  height: 50rpx;
  line-height: 50rpx;
  margin: 10rpx;
  border-radius: 10rpx;
  text-align: center;
  border: 6rpx transparent solid;
}
.theme-item.active {
  border-color: #6cc;
}
.story-setting-row {
  padding: 10rpx 0;
}
.setting-font-size {
  background-color: #666666;
  color: #fff;
  padding: 7rpx 20rpx;
}

.story-swiper {
  position: absolute;
  /* width: 100%; */
  height: 100%;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 0 20rpx;
}
</style>
